package com.walkline.util.ui;

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.io.HttpConnection;

import net.rim.device.api.io.IOUtilities;
import net.rim.device.api.io.transport.ConnectionDescriptor;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Characters;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.TouchEvent;
import net.rim.device.api.ui.XYEdges;

import com.walkline.app.WeiboAppConfig;
import com.walkline.util.BitmapMask;
import com.walkline.util.Enumerations.Friendshitp;
import com.walkline.util.Enumerations.RefreshAction;
import com.walkline.util.Function;
import com.walkline.util.GPATools;
import com.walkline.util.network.MyConnectionFactory;
import com.walkline.weibo.inf.User;

public class UserInfoListStyleButtonField extends Field
{
    public static int DRAWPOSITION_TOP = 0;
    public static int DRAWPOSITION_BOTTOM = 1;
    public static int DRAWPOSITION_MIDDLE = 2;
    public static int DRAWPOSITION_SINGLE = 3;
    
    private int CORNER_RADIUS = 12;

    private static final int HPADDING = Display.getWidth() <= 320 ? 4 : 6;
    private static final int VPADDING = 4;

    private static final int COLOR_BACKGROUND = 0xFFFFFF;
    private static final int COLOR_BORDER = 0xBBBBBB; //0x186DEF
    private static final int COLOR_BACKGROUND_FOCUS = 0x0A9000;

    private MyLabelField _labelTitle;
    private MyLabelField _labelValue;
    private MyLabelFieldWithNewline _labelDescription;
    private MyLabelField _labelDescriptionPreview;

    private Bitmap _avatarIcon;
    private Bitmap _arrowIcon;
    private User _user;

    private String _avatar_url;
    private byte[] _avatar_data;
    private int _avatar_size = 0;

    private int _rightOffset;
    private int _leftOffset;
    private int _labelHeight;
    private int _drawPosition = -1;

    /**
     * 显示标题图、标题、内容和描述，标题在最左边，内容在最右边，描述在标题下边，用于显示好友列表等
     * @param needAvator 是否显示标题图
     * @param title 标题
     * @param value 内容
     * @param description 描述
     */
    public UserInfoListStyleButtonField(boolean needAvator, String title, String value, String description)
    {
    	this((needAvator ? Bitmap.getBitmapResource("avatar.png") : null), title, value, description, Bitmap.getBitmapResource("not_followed.png"));
	}

    /**
     * 显示标题、内容和一个向右的箭头，标题在最左边，箭头在最右边，内容在箭头左边
     * @param title 标题
     * @param value 内容
     * @param needArrow 是否显示箭头
     */
    public UserInfoListStyleButtonField(String title, String value, boolean needArrow)
    {
        this(null, title, value, null, (needArrow ? Bitmap.getBitmapResource("arrow_right_black.png") : null));
    }

    public UserInfoListStyleButtonField(Bitmap avator, String title, String value, String description, Bitmap arrow)
    {
        super(USE_ALL_WIDTH | Field.FOCUSABLE);

        if (title != null) {_labelTitle = new MyLabelField(title); _labelTitle.setFont(WeiboAppConfig.FONT_SCREENNAME);}
        if (value != null) {_labelValue = new MyLabelField(value);}
        if (description != null) {_labelDescription = new MyLabelFieldWithNewline(description);}
        if (arrow != null) {_arrowIcon = arrow;}
        if (avator != null) {_avatarIcon = avator;}
    }

    /**
     * 好友样式列表，显示好友头像、好友名字、最近一条微博的预览内容和一个右边的箭头
     * @param user User类包含所需的信息
     */
    public UserInfoListStyleButtonField(User user)
    {
        super(USE_ALL_WIDTH | Field.FOCUSABLE);
        
        //ConnectionThread _connectionThread = new ConnectionThread();
        //if(!_connectionThread.isStarted()) {_connectionThread.start();}
        //_connectionThread.fetch(user.getProfileImageUrl());

        _avatar_url = user.getProfileImageUrl();
        String screen_name = user.getScreenName();
        //String status_text = user.getLastStatus() != null ? user.getLastStatus().getText() : "（无）";
        String description = user.getLocation() + " (微博: " + user.getStatusesCount() + " 好友: " + user.getFriendsCount() + " 粉丝: " + user.getFollowersCount() + " 收藏: " + user.getFavouritesCount() + ")";
        if (!user.getRemark().equals("")) {screen_name += " (" + user.getRemark() + ")";}

       	_labelTitle = new MyLabelField(screen_name + " (" + user.getGender()+")");
       	_labelTitle.setFont(WeiboAppConfig.FONT_SCREENNAME);

        _labelDescriptionPreview = new MyLabelField(description);
        _arrowIcon = Bitmap.getBitmapResource("arrow_right_black.png");
        _avatarIcon = Bitmap.getBitmapResource("avatar.png");
        _avatar_size = _avatarIcon.getWidth();
        _user = user;

        CORNER_RADIUS = 0;

		try {
			InputStream inputStream = getClass().getResourceAsStream("/img/avatar.png");
			byte[] data = IOUtilities.streamToBytes(inputStream);
			setAvatarData(data);
		} catch (IOException e) {Function.errorDialog(e.toString());}
    }

    public User getUser() {return _user;}

    public String getAvatarUrl() {return _avatar_url;}

    public byte[] getAvatarData() {return _avatar_data;}

    /**
     * 设置好友关系类型图标
     */
    public void setFriendship(int type)
    {
    	switch (type)
    	{
			case Friendshitp.FOLLOWME:
				_arrowIcon = Bitmap.getBitmapResource("follow_me.png");
				break;
			case Friendshitp.FOLLOWING:
				_arrowIcon = Bitmap.getBitmapResource("following.png");
				break;
			case Friendshitp.FOLLOWED:
				_arrowIcon = Bitmap.getBitmapResource("followed.png");
				break;
		}

    	updateLayout();
    }

    public void setAvatarData(byte[] data)
    {
    	_avatar_data = data;

		if (_avatar_data != null)
		{
			Bitmap newIcon = Bitmap.createBitmapFromBytes(_avatar_data, 0, -1, 1);

			_avatar_size = newIcon.getWidth();
			newIcon = GPATools.ResizeTransparentBitmap(newIcon, _avatar_size, _avatar_size, Bitmap.FILTER_LANCZOS, Bitmap.SCALE_STRETCH);

			BitmapMask mask = new BitmapMask(new XYEdges(5, 5, 5, 5), Bitmap.getBitmapResource("mask.png"));
			mask.applyMask(newIcon);

			_avatarIcon = newIcon;

			Manager m = getManager();
			if (m != null) {m.invalidate();}
		}
    }

    public void setDrawPosition(int drawPosition) {_drawPosition = drawPosition;}

    public void layout(int width, int height)
    {
        _leftOffset = HPADDING;

        if (_avatarIcon != null) {_leftOffset += _avatarIcon.getWidth() + HPADDING;}

        _rightOffset = HPADDING;
        if (_arrowIcon != null) {_rightOffset += _arrowIcon.getWidth() + HPADDING;}

        _labelTitle.layout(width - _leftOffset - _rightOffset, height);
        _labelHeight = _labelTitle.getHeight();

        if (_labelValue != null) {_labelValue.layout(width- _leftOffset - _rightOffset, height);}
        
        if (_labelDescription != null)
        {
        	_labelDescription.layout(width - _leftOffset - _rightOffset, height);
        	_labelHeight += _labelDescription.getHeight();
        } else if (_labelDescriptionPreview != null) {
        	_labelDescriptionPreview.layout(width - _leftOffset - _rightOffset, height);
        	_labelHeight += _labelDescriptionPreview.getHeight();
        }

        if (_avatarIcon != null) {_labelHeight = (_avatarIcon.getHeight() >= _labelHeight) ? _avatarIcon.getHeight() : _labelHeight;}

        setExtent(width, _labelHeight + 10);
    }

    public void setTitleText(String text)
    {
    	_labelTitle.setText(text);
        updateLayout();
    }
    
    public void setValueText(String text)
    {
    	_labelValue.setText(text);
    	updateLayout();
	}
    
    public void setDescription(String text)
    {
    	_labelDescription.setText(text);
    	updateLayout();
    }
    
    public void setAvatarIcon(byte[] icon)
    {
    	_avatarIcon = Bitmap.createBitmapFromBytes(icon, 0, -1, 1);
    }
    
    protected void paint(Graphics g)
    {
        // Avatar Bitmap
        if (_avatarIcon != null)
        {
            g.drawBitmap(HPADDING, (getHeight() - _avatarIcon.getHeight()) / 2, _avatarIcon.getWidth(), _avatarIcon.getHeight(), _avatarIcon, 0, 0);
        }

        // Title Text
        try {
            g.pushRegion(_leftOffset, (getHeight() - _labelHeight) / 2, getWidth() - _leftOffset - _rightOffset, _labelTitle.getHeight(), 0, 0);
            //_labelTitle.setFont(Config.FONT_SCREENNAME);
            _labelTitle.paint(g);
        } finally {g.popContext();}

        // Right Bitmap
        if (_arrowIcon != null)
        {
        	if (_arrowIcon.getWidth() < 50)
        	{
        		Bitmap action = g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? Bitmap.getBitmapResource("arrow_right.png") : Bitmap.getBitmapResource("arrow_right_black.png");
                g.drawBitmap(getWidth() - HPADDING - action.getWidth(), (getHeight() - action.getHeight()) / 2, action.getWidth(), action.getHeight(), action, 0, 0);	
        	} else {
        		g.drawBitmap(getWidth() - HPADDING - _arrowIcon.getWidth(), (getHeight() - _arrowIcon.getHeight()) / 2, _arrowIcon.getWidth(), _arrowIcon.getHeight(), _arrowIcon, 0, 0);
        	}
        }

        // Value Text
        if (_labelValue != null)
        {
        	try {
        		g.pushRegion(getWidth() - _labelValue.getWidth() - _rightOffset, (getHeight() - _labelValue.getHeight()) / 2,_labelValue.getWidth(), _labelValue.getHeight(), 0, 0);
        		_labelValue.paint(g);
        	} finally{g.popContext();}
        }

        // Description Text
        if (_labelDescription != null)
        {
        	try {
        		g.pushRegion(_leftOffset + HPADDING, getHeight() - _labelDescription.getHeight() - VPADDING, getWidth() - _leftOffset-_rightOffset, _labelDescription.getHeight(), 0, 0);
        		g.setColor(g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? Color.WHITE : Color.GRAY);
        		//g.setFont(Font.getDefault().derive(Font.PLAIN, Font.getDefault().getHeight(Ui.UNITS_pt)-1,Ui.UNITS_pt));
        		_labelDescription.paint(g);
        	} finally{g.popContext();}
        }else if (_labelDescriptionPreview != null) {
        	try {
        		g.pushRegion(_leftOffset + HPADDING,getHeight() - _labelDescriptionPreview.getHeight() - VPADDING,getWidth() - _leftOffset-_rightOffset, _labelDescriptionPreview.getHeight(), 0, 0);
        		g.setColor(g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? Color.WHITE : Color.GRAY);
        		//g.setFont(Font.getDefault().derive(Font.PLAIN, Font.getDefault().getHeight(Ui.UNITS_pt)-1,Ui.UNITS_pt));
        		_labelDescriptionPreview.paint(g);
        	} finally{g.popContext();}
        }
    }

    protected void paintBackground(Graphics g)
    {
        if(_drawPosition < 0)
        {
            super.paintBackground(g);
            return;
        }

        int oldColour = g.getColor();

        int background = g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? COLOR_BACKGROUND_FOCUS : COLOR_BACKGROUND;
        
        try {
            if(_drawPosition == 0)
            {
                // Top
                g.setColor(background);
                g.fillRoundRect(0, 0, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.setColor( COLOR_BORDER );
                g.drawRoundRect(0, 0, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
            } else if( _drawPosition == 1 ) {
                // Bottom 
                g.setColor(background);
                g.fillRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.setColor( COLOR_BORDER );
                g.drawRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
            } else if(_drawPosition == 2) {
                // Middle
                g.setColor(background);
                g.fillRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + 2 * CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.setColor( COLOR_BORDER );
                g.drawRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + 2 * CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
            } else {
                // Single
                g.setColor(background);
                g.fillRoundRect(0, 0, getWidth(), getHeight(), CORNER_RADIUS, CORNER_RADIUS);
                g.setColor(COLOR_BORDER);
                g.drawRoundRect(0, 0, getWidth(), getHeight(), CORNER_RADIUS, CORNER_RADIUS);
            }
        } finally {
            g.setColor(oldColour);
        }
    }
    
    protected void drawFocus(Graphics g, boolean on)
    {
        if(_drawPosition < 0)
        {
            super.drawFocus(g, on);
        } else {
            boolean oldDrawStyleFocus = g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS);
            try {
                if(on)
                {
                	g.setColor(Color.WHITE);
                    g.setDrawingStyle(Graphics.DRAWSTYLE_FOCUS, true);
                }
                
                paintBackground(g);
                paint(g);
            } finally {
                g.setDrawingStyle(Graphics.DRAWSTYLE_FOCUS, oldDrawStyleFocus);
            }
        }
    }
    
    protected boolean keyChar(char character, int status, int time) 
    {
        if(character == Characters.ENTER)
        {
            clickButton();
            return true;
        }
        
        return super.keyChar(character, status, time);
    }
    
    protected boolean navigationClick(int status, int time) 
    {
        clickButton(); 
        return true;    
    }
    
    protected boolean trackwheelClick(int status, int time)
    {        
        clickButton();    
        return true;
    }
    
    protected boolean invokeAction(int action) 
    {
        switch(action)
        {
            case ACTION_INVOKE:
                clickButton(); 
                return true;
        }
        
        return super.invokeAction(action);
    }
         
    public void clickButton() {fieldChangeNotify(0);}
       
    protected boolean touchEvent(TouchEvent message)
    {
        int x = message.getX(1);
        int y = message.getY(1);
        if(x < 0 || y < 0 || x > getExtent().width || y > getExtent().height) {return false;}
        
        switch(message.getEvent())
        {
        	case TouchEvent.CLICK:
                clickButton();
                return true;
        }
        
        return super.touchEvent(message);
    }

    public void setDirty(boolean dirty) {}
    public void setMuddy(boolean muddy) {}
    
    private class ConnectionThread extends Thread
    {
        private static final int TIMEOUT = 500;
        private String _theUrl;
        private volatile boolean _fetchStarted = false;
        private volatile boolean _stop = false;
        private byte[] data;

        private String getUrl() {return _theUrl;}
        
        private boolean isStarted() {return _fetchStarted;}            
     
        private void fetch(String url)
        {
            _fetchStarted = true;
            _theUrl = url;
        }

        private void stop() {_stop = true;}

        public void run()
        {
            for(;;)
            {
                while( !_fetchStarted && !_stop)  
                {
                    try {sleep(TIMEOUT);} catch (InterruptedException e) {Function.errorDialog(UserInfoListStyleButtonField.class.getName() + "\n\n" + "Thread#sleep threw " + e.toString());}
                }
                
                if (_stop) {return;}
                    
                MyConnectionFactory factory=new MyConnectionFactory();
                ConnectionDescriptor descriptor=factory.getConnection(getUrl());
                if(descriptor==null)
                {
                	_fetchStarted=false;
                	stop();
                	return;
                }
                
                HttpConnection httpConnection=(HttpConnection) descriptor.getConnection();
                InputStream inputStream=null;
                
                try 
                {               
					inputStream=httpConnection.openInputStream();
					if(inputStream.available()>0)
					{
						data=IOUtilities.streamToBytes(inputStream);
						
						if(data.length==httpConnection.getLength())
						{
							synchronized(Application.getEventLock())
							{
								Application.getApplication().invokeLater(new Runnable()
								{
									public void run()
									{
										setAvatarIcon(data);
										updateLayout();
									}
								});
							}
							
			                _fetchStarted = false;        
			                stop();
						}
					}
                } catch (IOException e) {
                } finally {
                	if(inputStream!=null) {try {inputStream.close();} catch (Exception e2) {}}
                	if(httpConnection!=null) {try {httpConnection.close();} catch (Exception e2) {}}
                }
            }
        }
    }
}